"""
报表模块 - 路由层
"""
from urllib.parse import quote
from datetime import datetime
from fastapi import APIRouter, Depends, Query
from fastapi.responses import StreamingResponse

from common.database import DatabaseService, get_db_dependency
from common.logger import create_logger
from common.response import PaginationParams, ApiResponse
from app.common.auth import require_report_view, require_report_export
from app.schemas.user_schemas import UserInDB
from app.schemas.report_schemas import (
    DeviceRunReportQuery,
    DeviceRunReportResponse,
    AlarmWorkReportQuery,
    AlarmWorkReportResponse,
)
from app.service import report_service

logger = create_logger(__name__)
router = APIRouter(prefix="/reports", tags=["报表管理"])


# 依赖注入别名
DbDep = DatabaseService


@router.get(
    "/device-run",
    response_model=ApiResponse[DeviceRunReportResponse],
    summary="获取设备运行报表"
)
async def get_device_run_report(
    db: DbDep = Depends(get_db_dependency),
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=100, description="每页大小"),
    query: DeviceRunReportQuery = Depends(),
    _: UserInDB = Depends(require_report_view),
) -> ApiResponse[DeviceRunReportResponse]:
    """
    获取设备运行报表（分页查询）
    
    查询参数：
    - keyword: 关键字（设备序列号模糊匹配）
    - start_date: 开始时间（设备创建时间范围）
    - end_date: 结束时间（设备创建时间范围）
    - status: 设备状态（单选或空）
    - manager_code: 负责人工号（单选或空）
    - page: 页码，默认1
    - size: 每页大小，默认20
    """
    try:
        logger.info(f"查询设备运行报表，参数: {query.model_dump()}, 分页: page={page}, size={size}")
        pagination = PaginationParams(page=page, size=size, keyword=None)
        result = await report_service.get_device_run_report(db, query, pagination)
        logger.info(f"设备运行报表查询成功，返回 {len(result.items)} 条记录")
        return ApiResponse.success(result, "设备运行报表获取成功")
    except Exception as e:
        logger.error(f"查询设备运行报表失败: {e}")
        return ApiResponse.error("查询设备运行报表失败", code=500)


@router.get(
    "/device-run/export",
    summary="导出设备运行报表"
)
async def export_device_run_report(
    db: DbDep = Depends(get_db_dependency),
    query: DeviceRunReportQuery = Depends(),
    _: UserInDB = Depends(require_report_export),
):
    """
    导出设备运行报表到Excel
    
    查询参数：
    - keyword: 关键字（设备序列号模糊匹配）
    - start_date: 开始时间（设备创建时间范围）
    - end_date: 结束时间（设备创建时间范围）
    - status: 设备状态（单选或空）
    - manager_code: 负责人工号（单选或空）
    
    注意：导出接口会返回全部数据，不分页
    """
    try:
        logger.info(f"导出设备运行报表，参数: {query.model_dump()}")
        excel_stream = await report_service.export_device_run_report(db, query)
        
        # 生成文件名（包含时间戳）
        filename = f"设备运行报表_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
        encoded_filename = quote(filename)
        
        logger.info(f"设备运行报表导出成功，文件名: {filename}")
        
        return StreamingResponse(
            excel_stream,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}"
            }
        )
    except Exception as e:
        logger.error(f"导出设备运行报表失败: {e}")
        return ApiResponse.error("导出设备运行报表失败", code=500)


@router.get(
    "/alarm-work",
    response_model=ApiResponse[AlarmWorkReportResponse],
    summary="获取告警工单报表"
)
async def get_alarm_work_report(
    db: DbDep = Depends(get_db_dependency),
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=100, description="每页大小"),
    query: AlarmWorkReportQuery = Depends(),
    _: UserInDB = Depends(require_report_view),
) -> ApiResponse[AlarmWorkReportResponse]:
    """
    获取告警工单报表（分页查询）
    
    查询参数：
    - keyword: 关键字（设备序列号模糊匹配）
    - start_date: 开始时间（告警发生时间范围）
    - end_date: 结束时间（告警发生时间范围）
    - alarm_status: 告警状态（单选或空）
    - priority: 优先级（单选或空）
    - page: 页码，默认1
    - size: 每页大小，默认20
    """
    try:
        logger.info(f"查询告警工单报表，参数: {query.model_dump()}, 分页: page={page}, size={size}")
        pagination = PaginationParams(page=page, size=size, keyword=None)
        result = await report_service.get_alarm_work_report(db, query, pagination)
        logger.info(f"告警工单报表查询成功，返回 {len(result.items)} 条记录")
        return ApiResponse.success(result, "告警工单报表获取成功")
    except Exception as e:
        logger.error(f"查询告警工单报表失败: {e}")
        return ApiResponse.error("查询告警工单报表失败", code=500)


@router.get(
    "/alarm-work/export",
    summary="导出告警工单报表"
)
async def export_alarm_work_report(
    db: DbDep = Depends(get_db_dependency),
    query: AlarmWorkReportQuery = Depends(),
    _: UserInDB = Depends(require_report_export),
):
    """
    导出告警工单报表到Excel
    
    查询参数：
    - keyword: 关键字（设备序列号模糊匹配）
    - start_date: 开始时间（告警发生时间范围）
    - end_date: 结束时间（告警发生时间范围）
    - alarm_status: 告警状态（单选或空）
    - priority: 优先级（单选或空）
    
    注意：导出接口会返回全部数据，不分页
    """
    try:
        logger.info(f"导出告警工单报表，参数: {query.model_dump()}")
        excel_stream = await report_service.export_alarm_work_report(db, query)
        
        # 生成文件名（包含时间戳）
        filename = f"告警工单报表_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
        encoded_filename = quote(filename)
        
        logger.info(f"告警工单报表导出成功，文件名: {filename}")
        
        return StreamingResponse(
            excel_stream,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}"
            }
        )
    except Exception as e:
        logger.error(f"导出告警工单报表失败: {e}")
        return ApiResponse.error("导出告警工单报表失败", code=500)
